home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume21 / amd / part10 < prev    next >
Encoding:
Internet Message Format  |  1990-04-10  |  44.1 KB

  1. Subject:  v21i098:  An Automounter for NFS systems, Part10/13
  2. Newsgroups: comp.sources.unix
  3. Approved: rsalz@uunet.UU.NET
  4. X-Checksum-Snefru: 86b80fdc f701c80d c01c2400 27bda240
  5.  
  6. Submitted-by: Jan-Simon Pendry <jsp@doc.ic.ac.uk>
  7. Posting-number: Volume 21, Issue 98
  8. Archive-name: amd/part10
  9.  
  10. #! /bin/sh
  11. # This is a shell archive.  Remove anything before this line, then unpack
  12. # it by saving it into a file and typing "sh file".  To overwrite existing
  13. # files, type "sh file -c".  You can also feed this as standard input via
  14. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  15. # will see the following message at the end:
  16. #        "End of archive 10 (of 13)."
  17. # Contents:  ChangeLog map.c
  18. # Wrapped by rsalz@papaya.bbn.com on Tue Apr 10 15:12:14 1990
  19. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  20. if test -f 'ChangeLog' -a "${1}" != "-c" ; then 
  21.   echo shar: Will not clobber existing file \"'ChangeLog'\"
  22. else
  23. echo shar: Extracting \"'ChangeLog'\" \(21923 characters\)
  24. sed "s/^X//" >'ChangeLog' <<'END_OF_FILE'
  25. XThu Jan 11 16:56:41 1990  Jan-Simon Pendry  (jsp at achilles)
  26. X
  27. X    * Release 5.1c.
  28. X
  29. X    * (amq*) has new options.  -f flushes the map cache and -m prints
  30. X    information about mounted filesystem and fileservers.
  31. X
  32. XTue Jan  2 14:44:21 1990  Jan-Simon Pendry  (jsp at achilles)
  33. X
  34. X    * (util.c) am_mounted() patches the path for "direct" mounted
  35. X    filesystems - cosmetic.
  36. X
  37. X    * (afs_ops.c) when possible sets a small kernel attribute cache
  38. X    timeout on the automount points.
  39. X
  40. X    * (nfs_stubs.c) delete() and rmdir() operations implemented.  Used
  41. X    when a mount point is timed out so the kernel name cache gets to
  42. X    know about the changes.  Fixes most ESTALE errors.
  43. X
  44. X    * (nfs_stubs.c) New do_readlink() function added.  This is used to
  45. X    make sure that a filesystem is mounted at the time a link is read
  46. X    in the case of "direct" mounts.  Done so that the length of the
  47. X    link is available when the initial getattr is done on the mountpoint.
  48. X
  49. X    * (sfs_ops.c) Changed implementation to avoid race conditions.
  50. X    The link target is re-arranged so that sublink points to the
  51. X    target and fs always points at ".".
  52. X
  53. X    * Fixed mount flag bug on Ultrix.
  54. X
  55. X    * Added support from Sjoerd Mullender for Alliant FX/4 and Encore
  56. X    Multimax.
  57. X
  58. XThu Dec  7 17:55:29 1989  Jan-Simon Pendry  (jsp at achilles)
  59. X
  60. X    * (afs_ops.c) dfs_readlink now does a new_ttl on the node it
  61. X    returns.
  62. X
  63. X    * (afs_ops.c) next_nonerror_node now implements the task after
  64. X    which it is named.
  65. X
  66. XTue Nov 28 17:20:52 1989  Jan-Simon Pendry  (jsp at achilles)
  67. X
  68. X    * Release 5.1b.
  69. X
  70. X    * (restart.c) Generates link nodes for any unrecognised filesystem
  71. X    types and then marks them so that they are never deleted (since
  72. X    they could never be automounted later).
  73. X
  74. X    * (os-*.h) Irrelevant #undef's deleted.
  75. X
  76. X    * (arch) Now knows about AIX on RTs.
  77. X
  78. X    * (amq.c) Rationalised the output.  Now only gives you what you
  79. X    asked for.
  80. X
  81. X    * (am.h) New macro: FSRV_ISDOWN(fs), which checks whether a
  82. X    fileserver is down.
  83. X
  84. X    * (afs_ops.c) When a mount fails due to a timeout the underlying
  85. X    filesystem is ripped away and replaced with an error fs.  This
  86. X    avoids the possibility of being left with a single error reference
  87. X    to a valid mounted filesystem.
  88. X
  89. XThu Nov 23 18:04:29 1989  Jan-Simon Pendry  (jsp at achilles)
  90. X
  91. X    * (nfs_start.c) Re-order bootstrap sequence to avoid potential
  92. X    deadlock if restart() ends up accessing one of the automount points.
  93. X
  94. X    * (amq.c) Don't produce default mount output if one of the -l, -x
  95. X    or -D options was used.
  96. X
  97. X    * (umount_fs.c) Add alternative unmount routine for 4.4 BSD.
  98. X
  99. XMon Nov 20 16:22:50 1989  Jan-Simon Pendry  (jsp at achilles)
  100. X
  101. X    * (os-bsd44.h) Fixed redefinition of UMOUNT_FS.
  102. X
  103. X    * (info_ndbm.c) Added missing #include <sys/stat.h>.
  104. X
  105. X    * (mapc.c) Fixed typo in ifdef around gdbm config entry.
  106. X
  107. XSat Nov 18 16:39:13 1989  Jan-Simon Pendry  (jsp at achilles)
  108. X
  109. X    * (util.c) If "/" is automounted, make sure it is never timed out.
  110. X
  111. X    * (mtab.c) Missing clock invalidation added in read_mtab (from a file).
  112. X
  113. X    * (mntfs.c) realloc_mntfs simplified.
  114. X
  115. X    * (map.c) Closed a race condition during shutdown when second and
  116. X    subsequent duplicate mounts were deleted prematurely.
  117. X
  118. X    * (afs_ops.c) Duplicate mounts are now given the correct return
  119. X    code.
  120. X
  121. XFri Nov 17 18:58:18 1989  Jan-Simon Pendry  (jsp at achilles)
  122. X
  123. X    * 5.1 Release.
  124. X
  125. XThu Nov 16 17:57:02 1989  Jan-Simon Pendry  (jsp at achilles)
  126. X
  127. X    * (mntfs.c) Make sure inherit mntfs structures are not cached
  128. X    after last reference; otherwise a second reference to the
  129. X    inherited filesystem will get stuck on the inherit rather than the
  130. X    (now) fully mounted filesystem.
  131. X
  132. X    * (am.c, nfs_start.c) After forking the server, make sure the
  133. X    parent does not exit until the automount points are mounted.  This
  134. X    allows a clean sequence during system startup.
  135. X
  136. X    * Initial port to 4.4 BSD.  Several new configuration abstractions
  137. X    were added to make this port possible.
  138. X
  139. XThu Nov  9 21:42:14 1989  Jan-Simon Pendry  (jsp at achilles)
  140. X
  141. X    * (afs_ops.c, opts.c) Added map logging to facilitate mount map
  142. X    debugging without needing a -DDEBUG version of Amd.
  143. X
  144. X    * (afs_ops.c) Make sure the length of the fs_hostname mount
  145. X    parameter does not exceed MAXHOSTNAMESZ.
  146. X
  147. XWed Nov  8 13:44:02 1989  Jan-Simon Pendry  (jsp at achilles)
  148. X
  149. X    * Change the message log format to indicate the severity of the
  150. X    message to allow simpler analysis of the log file.
  151. X
  152. XTue Nov  7 14:11:36 1989  Jan-Simon Pendry  (jsp at achilles)
  153. X
  154. X    * 5.0 Patchlevel 11.
  155. X
  156. X    * (os-bsd44.h) Initial guess at 4.4 BSD definitions.
  157. X
  158. X    * (os-aux.h) Port for Macintosh II from Julian Onions.
  159. X
  160. X    * (amq.c) Output formats cleaned up.  AMQ_MNTTREE is still broken
  161. X    in amq_subr.c though.
  162. X
  163. X    * (afs_ops.c) If a mount timed out, for example an NFS server was
  164. X    down at the time, it was possible for the error code to remain
  165. X    unset thus jamming that mount node in a state from which it could
  166. X    not recover.  Just make sure that the mf_error field gets filled
  167. X    in when an error occurs.
  168. X
  169. X    * (afs_ops.c) strsplit is run over /defaults to avoid problems
  170. X    with whitespace creeping in.
  171. X
  172. XSun Nov  5 11:50:51 1989  Jan-Simon Pendry  (jsp at achilles)
  173. X
  174. X    * (util.c) am_mounted: Added missing initialisation of stats.s_mtime.
  175. X
  176. XFri Nov  3 17:33:02 1989  Jan-Simon Pendry  (jsp at achilles)
  177. X
  178. X    * 5.0 Patchlevel 10.
  179. X
  180. X    * Changed the copyright.
  181. X
  182. XThu Nov  2 17:07:53 1989  Jan-Simon Pendry  (jsp at achilles)
  183. X
  184. X    * 5.0 Patchlevel 9.
  185. X
  186. X    * (opts.c) new option syntax: == != :=
  187. X
  188. X    * (nfs_ops.c) Less caching of filehandles.  Now cached errors are
  189. X    discarded after use.
  190. X
  191. X    * (mtab.c) now attempts to deal with a lack of open file slots (ENFILE).
  192. X
  193. X    * (mount_fs.c) automount entries in the mount table now have a
  194. X    dev= entry in the same way as NFS and UFS.
  195. X
  196. X    * (mntfs.c) mntfs nodes are now cached after the last reference
  197. X    and discarded <ALLOWED_MOUNT_TIME> seconds later.  This avoids
  198. X    thrashing during a mount.
  199. X
  200. X    * (mapc.c) map default cache mode is now selected with
  201. X    "mapdefault", not "default"
  202. X
  203. X    * (amd.tex) numerous clarifications.  Still more work required...
  204. X
  205. X    * (amq_subr.c) now allows the -x option of amq to operate.
  206. X
  207. X    * (afs_ops.c) afs_bgmount now keeps track of which filesystem
  208. X    needed retrying and ensures that the mount node in the
  209. X    continuation correctly points at an unmounted filesystem.  This
  210. X    fixes a problem whereby a valid mounted filesystem could appear to
  211. X    have failed to mount.
  212. X
  213. X    * Configure now gives more of a running commentary and checks
  214. X    whether os-type and arch actually worked.
  215. X
  216. X    * Allow spurious ';'s in a mount location.
  217. X
  218. XFri Oct 27 14:03:31 1989  Jan-Simon Pendry  (jsp at achilles)
  219. X
  220. X    * foo=blah changed to foo:=blah, foo==blah and foo!=blah.
  221. X
  222. X    * -l stderr changed to -l /dev/stderr.
  223. X
  224. XThu Oct 19 15:34:28 1989  Jan-Simon Pendry  (jsp at achilles)
  225. X
  226. X    * 5.0 Patchlevel 6.
  227. X
  228. X    * LOG_INFO messages have been rationalised so that some
  229. X    statistics, graphs and so on can be generated.
  230. X
  231. X    * Transaction ID's for RPC calls are now allocated by the
  232. X    individual callers, rather than from a central pool.  This
  233. X    decreases the load on mount daemons and NFS servers since the
  234. X    same XID is used for retries when needed.
  235. X
  236. X    * Many fine details of the new data structures have been changed.
  237. X    Some areas have been optimized.
  238. X
  239. XFri Oct 13 12:31:26 1989  Jan-Simon Pendry  (jsp at achilles)
  240. X
  241. X    * Restart code re-implemented to work with the new data structures.
  242. X
  243. X    * Fine tuning applied to new NFS server modeling code.
  244. X
  245. XThu Oct 12 15:57:24 1989  Jan-Simon Pendry  (jsp at achilles)
  246. X
  247. X    * Added ${/var} and ${var/} variable expansions.  The first gives
  248. X    the "basename" component of the variable, the latter gives the
  249. X    "dirname" component.  Additionally, spurious /'s are deleted after
  250. X    the variable expansions is complete.
  251. X
  252. X    * Added new -C option to allow the machine's cluster name to be
  253. X    given to amd.  ${cluster} fetches the value and can be used as
  254. X    another selector.
  255. X
  256. X    * Broken the major data struct (am_node) into three layers:
  257. X    am_node (one for each automount node), mntfs (one for each mounted
  258. X    filesystem) and fserver (one for each file server).  Machine
  259. X    up/down state is maintained in the fserver layer.  Filesystem
  260. X    mount/unmount state is maintained in the mntfs layer.  This change
  261. X    fixes the last known major problem caused by the lack of a central
  262. X    focus for filesystem and fileserver status.  There is a dummy file
  263. X    server layer for local filesystems (ufs, link, program, error).
  264. X
  265. XTue Oct 10 11:15:42 1989  Jan-Simon Pendry  (jsp at achilles)
  266. X
  267. X    * 5.0 Patchlevel 5.
  268. X
  269. X    * (nfs_ops.c) the filehandle cache is now flushed when a
  270. X    filesystem is unmounted.  This avoids ending up with stale
  271. X    information if a server bounces.
  272. X
  273. X    * (clock.c) new module to implement callouts.  Many other
  274. X    routines changed to use callouts instead of messing with ttl
  275. X    fields.
  276. X
  277. XSun Oct  1 17:08:20 1989  Jan-Simon Pendry  (jsp at achilles)
  278. X
  279. X    * 5.0 Patchlevel 3 & 4.
  280. X
  281. X    * Numerous cleanups.
  282. X
  283. XWed Sep 13 14:30:05 1989  Jan-Simon Pendry  (jsp at achilles)
  284. X
  285. X    * 5.0 Patchlevel 2.
  286. X
  287. X    * (nfs_ops.c) portmap information is not remembered beyond the
  288. X    basic filehandle cache interval.  That avoids problems when a new
  289. X    portmap and/or rpc.mountd is started and the bound port changes.
  290. X
  291. X    * (mapc.c) cache reloads are automatically done every hour.
  292. X
  293. X    * Removed xlog macro in favour of plog() so that the log level
  294. X    can be reflected through to syslog().  log() routine renamed to
  295. X    plog() which takes an extra parameter indicating the log level.
  296. X
  297. XTue Sep  5 20:00:19 1989  Jan-Simon Pendry  (jsp at achilles)
  298. X
  299. X    * (nfs_ops.c) when a server is known to be down, any cached file
  300. X    handles and port mapping informaton is flushed since that may have
  301. X    changed when it comes back up.
  302. X
  303. X    * (map.c) timeout no longer attempts to unmount a hung mount point.
  304. X
  305. XMon Sep  4 14:49:18 1989  Jan-Simon Pendry  (jsp at achilles)
  306. X
  307. X    * (afs_ops.c) a mount node which timed out during mount is now
  308. X    retained for the normal timeout interval rather than for a short
  309. X    period.  This avoids wasting time retrying mounts from a server
  310. X    which is down.
  311. X
  312. X    * (afs_ops.c) hung mounts are now detected and not used as a
  313. X    duplicate mount - something which defeated the replacement fs
  314. X    scheme.
  315. X
  316. X    * (nfs_ops.c) keepalive's now back-off when a server has gone
  317. X    down.
  318. X
  319. XThu Aug 31 21:18:35 1989  Jan-Simon Pendry  (jsp at achilles)
  320. X
  321. X    * 5.0 Patchlevel 1.
  322. X
  323. X    * Fixed several bugs which showed up in the keepalive
  324. X    implementation when a gateway went down causing
  325. X    a different sequence of errors than usual.
  326. X
  327. XWed Aug 30 11:29:21 1989  Jan-Simon Pendry  (jsp at achilles)
  328. X
  329. X    * (amq.x) now uses a Sun assigned program number.
  330. X
  331. X    * Revision 5.0 - can now start using metaconfig.
  332. X
  333. XTue Aug 29 14:36:48 1989  Jan-Simon Pendry  (jsp at achilles)
  334. X
  335. X    * (os-u3_0.h, os-type) now knows about DECstations (mips).
  336. X
  337. X    * (nfs_stubs.c) Added hooks to readlink entry point to call
  338. X    per-fs readlink routine if it exists, otherwise old behaviour.
  339. X
  340. X    * (afs_ops.c) Added implementation of "type=direct".  This is
  341. X    the same as "type=auto" but is itself the link to the
  342. X    mount point, rather than being a directory containing a list
  343. X    of links to mount points.
  344. X
  345. XMon Aug 28 17:48:15 1989  Jan-Simon Pendry  (jsp at achilles)
  346. X
  347. X    * (afs_ops.c) Changed readdir to workaround a problem on
  348. X    ultrix 3 where it seems to forget that eof has been reached.
  349. X
  350. XThu Aug 24 15:17:55 1989  Jan-Simon Pendry  (jsp at achilles)
  351. X
  352. X    * Created "beta16".
  353. X
  354. X    * (afs_ops.c) /defaults is located along with every key.
  355. X    this makes it possible to update the /defaults in
  356. X    a map and get to use it.
  357. X
  358. X    * (mapc.c) added map cache synchronization support.  if
  359. X    a file or ndbm map is updated the cache is junked so avoiding
  360. X    things getting out of sync.
  361. X
  362. XWed Aug 23 19:17:52 1989  Jan-Simon Pendry  (jsp at achilles)
  363. X
  364. X    * (os-u3_0.h) new file to support Ultrix 3.0
  365. X
  366. X    * (opts.c) allow environment variables to be accessed via
  367. X    the same ${env} syntax used for options & selectors.
  368. X
  369. XTue Aug 22 13:19:49 1989  Jan-Simon Pendry  (jsp at achilles)
  370. X
  371. X    * (opts.c, get_args.c) added support for kernel architecture
  372. X    type to allow /usr/kvm to be automounted under SunOS 4.x.
  373. X
  374. X    * (os-xinu43.h) updated for june '89 release of MORE/bsd.
  375. X
  376. X    * (opts.c) fixed memory allocation problems where some strings
  377. X    may not have been strdup'ed before they were free'ed so causing
  378. X    the malloc arena to get into a twist.  This caused core dumps on
  379. X    some machines and infinite loops on others.
  380. X
  381. X    * (*.c) clock handling is now done by a macro.  Global variable
  382. X    clock_valid is > 0 (ie the time) when valid, 0 if invalid.
  383. X
  384. X    * (map.c) timeout code survived a complete rewrite and is now
  385. X    O(n) rather than O(n^2).
  386. X
  387. X    * (info_hes.c) new database hooks for Hesiod nameserver.
  388. X
  389. X    * (get_args.c) the local sub-domain is picked up from the
  390. X    hostname if it is not specifed with -d.  The subdomain is
  391. X    then stripped from the hostname.
  392. X
  393. X    * (am.c) when a SIGTERM is received, an immediate abort
  394. X    occurs - only the top-level automounts are unmounted; all
  395. X    other mounts stay -- use amd -r to restart.
  396. X
  397. X    * (afs_ops.c) cleaned up key prefix handling.  Again updated
  398. X    the "hostname" string passed to the kernel so that includes
  399. X    the hostname, pid and mount point.
  400. X
  401. XTue Aug  8 16:05:23 1989  Jan-Simon Pendry  (jsp at achilles)
  402. X
  403. X    * (nfs_ops.c) changed the way the file handle cache is managed.
  404. X    No longer gets a race condition between something entering the
  405. X    cache and being used and discard.
  406. X
  407. XTue Jul 25 20:40:51 1989  Jan-Simon Pendry  (jsp at achilles)
  408. X
  409. X    * (map.c) changed fh_to_mp2 so that it does not return
  410. X    ESTALE during shutdown.  it returns ENOENT instead which
  411. X    avoids thrashing with the kernel.
  412. X
  413. XSun Jul 23 15:06:10 1989  Jan-Simon Pendry  (jsp at achilles)
  414. X
  415. X    * (afs_ops.c) make sure the incoming key from the kernel
  416. X    does not contain any characters which could cause trouble
  417. X    during macro expansion (such as `"! etc).
  418. X
  419. X    * (afs_ops.c) fixed contruction of "mtab" entry.
  420. X
  421. XFri Jul 21 11:01:05 1989  Jan-Simon Pendry  (jsp at achilles)
  422. X
  423. X    * (afs_ops.c) some changes to support the new startup
  424. X    shutdown scheme.
  425. X
  426. X    * (map.c) startup and shutdown are now done using the
  427. X    standard interfaces.  Startup is done by creating a
  428. X    private cache map  ";root;" and then doing lookups
  429. X    on all the names in it.  Shutdown is done by forcibly
  430. X    timing out all the mount points including the automount
  431. X    points.
  432. X
  433. X    * (info_*.c) modified to provide interface required by
  434. X    mapc.c module.
  435. X
  436. X    * (mapc.c) new module to implement map caching.  Caching
  437. X    can be controlled by an fs option.  "all" means cache
  438. X    the entire map (if possible).  "inc" means cache things
  439. X    incrementally.  "none" means never cache things.  Each
  440. X    map type has a default caching mode which is used if
  441. X    cache option "default" is used.
  442. X
  443. XWed Jul 19 16:14:52 1989  Jan-Simon Pendry  (jsp at achilles)
  444. X
  445. X    * (sched.c) implements a general sleep/wakeup scheme and uses
  446. X    it for sub-process handling.
  447. X
  448. X    * (nfs_start.c) task_notify() called from where it used to
  449. X    be called.
  450. X
  451. X    * (nfs_ops.c) now implements a non-blocking rpc library.
  452. X    Everything in nfs_ops was changed to use it.  This should
  453. X    not be in this file and will be moved later. 
  454. X
  455. X    * (map.c) if a mount point times out and it is deferred then
  456. X    issue a wakeup so that it can be retried.
  457. X
  458. X    * (map.c) when creating a new mount point fetches the entry
  459. X    "/defaults" from the associated map if no other options are
  460. X    specified.
  461. X
  462. X    * (am.c) implements the -p (print process id) option.
  463. X
  464. X    * (afs_ops.c) a mount attempt now has a time-to-live of twenty
  465. X    seconds.  if only deferred attempts are waiting after that
  466. X    interval the kernel gets sent ETIMEDOUT.
  467. X
  468. X    * (afs_ops.c) the name by which the kernel knows the filesystem
  469. X    has changed from pid%d@host to /mountpoint@host.  That looks
  470. X    better to users who get hit by it.
  471. X
  472. XFri Jul 14 18:46:16 1989  Jan-Simon Pendry  (jsp at achilles)
  473. X
  474. X    * (afs_ops.c) now knows about defered mounts - mounts which
  475. X    are not in progress, not completed, and not failed.
  476. X
  477. X    * (sched.c) added new entry point sched_ast().  This simulates
  478. X    a completed job.  The basic idea is to let something else return
  479. X    to the main scheduling loop with a guarentee that it will be
  480. X    called back when some other action has taken place.
  481. X
  482. X    * (nfs_ops.c) implemented a file handle cache.  The nfs_init
  483. X    routine starts up a request for the filehandle and the mount
  484. X    routine uses it when it arrives.
  485. X
  486. XThu Jul 13 18:07:58 1989  Jan-Simon Pendry  (jsp at achilles)
  487. X
  488. X    * (afs_ops.c) found a race condition between an error occuring
  489. X    and the am_node being timed out.  Fixed by updating the
  490. X    time-to-live and keepalive counters in the node whenever
  491. X    AMF_MOUNTING is cleared.  Also changed afs_lookuppn() so that
  492. X    it doesn't destroy the node when it returns the error code.
  493. X    This stops thrashing and the node is eventually timed out.
  494. X    Now the only way a node gets deleted is by the timeout code
  495. X    which seems more elegant.
  496. X
  497. XTue Jul 11 15:36:44 1989  Jan-Simon Pendry  (jsp at achilles)
  498. X
  499. X    * Created "beta15".
  500. X
  501. X    * Fixed *all* references to "u2.2".  Some where missed in
  502. X    the original change.  They are now u2_2.
  503. X
  504. X    * (mk-amd-map.c) new command.  Converts plain files into
  505. X    ndbm databases for use by the info_ndbm module.  Hooks
  506. X    included for future support for gdbm just as soon as I
  507. X    can get a copy.
  508. X
  509. XSun Jul  9 19:00:22 1989  Jan-Simon Pendry  (jsp at achilles)
  510. X
  511. X    * Created "beta14".
  512. X
  513. X    * (get_info.c) code to handle yp and files now split into
  514. X    new files info_yp.c and info_file.c  New support for ndbm
  515. X    databases is in info_ndbm.c.  A table in get_info.c controls
  516. X    what and in which order things are searched.
  517. X
  518. X    * (map.c, nfs_stubs.c) better handling for hung mount points.
  519. X    if a filehandle is passed in by the kernel which references
  520. X    a hung node, then try to find a replacement, possibly by calling
  521. X    lookup explicitly.
  522. X
  523. X    * (*.c) use new xlog(level)(message) interface
  524. X
  525. XThu Jun  8 20:28:55 1989  Jan-Simon Pendry  (jsp at achilles)
  526. X
  527. X    * (nfs_ops.c, ufs_ops.c) when compiled with DEBUG, display
  528. X    the fs options being used.
  529. X
  530. X    * (am.c) make test for root a little more polite.
  531. X
  532. X    * (get_args.c) update Usage message to include -r option.
  533. X
  534. XWed Jun  7 16:28:51 1989  Jan-Simon Pendry  (jsp at achilles)
  535. X
  536. X    * (rpc_fwd.c) fwd_reply: if the recvfrom call fails because it
  537. X    is interrupted then try again.
  538. X
  539. XTue Jun  6 16:39:15 1989  Jan-Simon Pendry  (jsp at achilles)
  540. X
  541. X    * Created "beta12".
  542. X
  543. X    * (afs_ops.c) inheriting mount option list from command line
  544. X    is now cumulative.  A -foo on the command line is prepended
  545. X    to the default option list taken from the map.  This can be
  546. X    used to override the ``default default'' options in opts.c.
  547. X
  548. X    * (get_args.c, am.c) added new -r (restart) option.  Restart of
  549. X    mounted filesystems is only done if this option is specified.
  550. X    Should *not* be specified in /etc/rc.local of course.
  551. X
  552. X    * (yp_master.c) make the enumeration error message more verbose
  553. X    when debugging is enabled.
  554. X
  555. X    * (rpc_fwd.c) rearranged some declarations at the top.  Removed
  556. X    a spurious call to free which was causing grief on some systems,
  557. X    but not on Sun's.  [This problem was the reason for implementing
  558. X    the -D mem option.]
  559. X
  560. X    * (opts.c) make sure opt_key and opt_path are set to a zero
  561. X    length string unless otherwise specified.  Previously they
  562. X    were are source of dangling pointers.
  563. X
  564. X    * (nfs_ops.c) make sure that the allocated nfs_private identifiers
  565. X    are unique even when some filesystem are being restarted.  This mean
  566. X    starting the basic allocation from 1, not zero.
  567. X
  568. X    * (am.h, get_args.c, util.c) added definition and implmentation of
  569. X    a simple memory allocation trace (D_MEM).
  570. X
  571. X    * (afs_ops.c) afs_lookuppn: tightened up memory allocation and
  572. X    delay string copying until last possible moment.
  573. X
  574. XMon Jun  5 18:01:18 1989  Jan-Simon Pendry  (jsp at achilles)
  575. X
  576. X    * (Makefile.com) diffs: added new rule to generate diffs
  577. X    between versions.
  578. X
  579. X    * (get_info.c) search_file: added a new dlog() to note when
  580. X    wildcards are returned.
  581. X
  582. X    * (afs_ops.c) afs_lookuppn: call to init_map specifies efs as
  583. X    the default ops structure.  If the location list only contained
  584. X    defaults and no real mounts then this previously caused a null
  585. X    pointer dereference.
  586. X
  587. X    * (map.c) last_used_map: Added new variable.  Keeps track of the
  588. X    last used map, which may be wildly different from first_free_map.
  589. X    This fixes bugs in several routines in this file.
  590. X
  591. X    * (util.c) mkdirs, rmdirs: Changed directory make/unmake.  It is
  592. X    not possible to quickly determine how many directories need to
  593. X    be created or deleted, so we try to make as many as possible.
  594. X
  595. X    * (opts.c) Added default values for rfs, rhost and fs.
  596. X    The new defaults guarentee unique names to allow the NFS
  597. X    keepalive stuff to work.
  598. X
  599. XSun Jun  4 16:12:15 1989  Jan-Simon Pendry  (jsp at achilles)
  600. X
  601. X    * First draft of documentation included in the next release.
  602. X
  603. X    * Hooks for TFS added, though this still requires a lot of work.
  604. X
  605. X    * Re-implemented option handling.  Options are now allocated
  606. X    dynamically on a per-mount basis in the continuation structure.
  607. X
  608. X    * Changed os type u2.2 to u2_2 to allow for regular expression
  609. X    matching in selectors.
  610. X
  611. X    * Format of mount maps is now entirely different.  Instead of
  612. X    guessing which filesystem type is being used, it is now explicitly
  613. X    stated along with the required options.  Variable expansion is
  614. X    done on the options and selectors are also implemented.  The
  615. X    requested name can also contain any of the selectors.
  616. X
  617. XWed May 24 15:21:39 1989  Jan-Simon Pendry  (jsp at achilles)
  618. X
  619. X    * Re-implemented NFS ping algorithm to use the new RPC forwarding
  620. X    system.  This allowed a large amount of nfs_ops specific code
  621. X    to be removed from nfs_start.c and moved to nfs_ops.c.
  622. X    There is still no strategy for hung file systems.  At the moment
  623. X    it will merely try to mount an alternative (or the same again)
  624. X    to the same place in the file system.
  625. X
  626. X    * Added RPC forwarding package.  This supports general RPC gatewaying
  627. X    over a UDP transport.  The idea is to put a packet identifier into
  628. X    each outgoing RPC packet and then match that up in a database when
  629. X    a reply comes in.  The database records the original packet identifier
  630. X    (so that it can be replaced), the source address for the packet and
  631. X    a function to call to do the forwarding.
  632. X
  633. X    * ChangeLog added between beta8 and beta9.  Should have done this sooner.
  634. END_OF_FILE
  635. if test 21923 -ne `wc -c <'ChangeLog'`; then
  636.     echo shar: \"'ChangeLog'\" unpacked with wrong size!
  637. fi
  638. # end of 'ChangeLog'
  639. fi
  640. if test -f 'map.c' -a "${1}" != "-c" ; then 
  641.   echo shar: Will not clobber existing file \"'map.c'\"
  642. else
  643. echo shar: Extracting \"'map.c'\" \(19814 characters\)
  644. sed "s/^X//" >'map.c' <<'END_OF_FILE'
  645. X/*
  646. X * $Id: map.c,v 5.1.1.3 90/01/11 17:08:32 jsp Exp Locker: jsp $
  647. X *
  648. X * Copyright (c) 1990 Jan-Simon Pendry
  649. X * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
  650. X * Copyright (c) 1990 The Regents of the University of California.
  651. X * All rights reserved.
  652. X *
  653. X * This code is derived from software contributed to Berkeley by
  654. X * Jan-Simon Pendry at Imperial College, London.
  655. X *
  656. X * Redistribution and use in source and binary forms are permitted
  657. X * provided that the above copyright notice and this paragraph are
  658. X * duplicated in all such forms and that any documentation,
  659. X * advertising materials, and other materials related to such
  660. X * distribution and use acknowledge that the software was developed
  661. X * by Imperial College of Science, Technology and Medicine, London, UK.
  662. X * The names of the College and University may not be used to endorse
  663. X * or promote products derived from this software without specific
  664. X * prior written permission.
  665. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  666. X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  667. X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  668. X *
  669. X *    %W% (Berkeley) %G%
  670. X */
  671. X
  672. X#include "am.h"
  673. X#include <sys/param.h>    /* For NMOUNT */
  674. X
  675. X/*
  676. X * Generation Numbers.
  677. X *
  678. X * Generation numbers are allocated to every node created
  679. X * by amd.  When a filehandle is computed and sent to the
  680. X * kernel, the generation number makes sure that it is safe
  681. X * to reallocate a node slot even when the kernel has a cached
  682. X * reference to its old incarnation.
  683. X * No garbage collection is done, since it is assumed that
  684. X * there is no way that 2^32 generation numbers could ever
  685. X * be allocated by a single run of amd - there is simply
  686. X * not enough cpu time available.
  687. X */
  688. Xstatic unsigned int am_gen = 2;    /* Initial generation number */
  689. X#define new_gen() (am_gen++)
  690. X
  691. Xstruct am_node *exported_ap[NEXP_AP];
  692. Xint first_free_map = 0;        /* First available free slot */
  693. Xint last_used_map = -1;        /* Last unavailable used slot */
  694. Xstatic int timeout_mp_id;    /* Id from last call to timeout */
  695. X
  696. X/*
  697. X * The root of the mount tree.
  698. X */
  699. Xstatic am_node *root_node;
  700. X
  701. X/*
  702. X * Allocate a new mount slot and create
  703. X * a new node.
  704. X * Fills in the map number of the node,
  705. X * but leaves everything else uninitialised.
  706. X */
  707. Xstruct am_node *exported_ap_alloc(P_void)
  708. X{
  709. X    struct am_node *mp, **mpp;
  710. X
  711. X    /*
  712. X     * First check if there are any slots left
  713. X     */
  714. X    if (first_free_map >= NEXP_AP)
  715. X        return 0;
  716. X
  717. X    /*
  718. X     * Grab the next free slot
  719. X     */
  720. X    mpp = exported_ap + first_free_map;
  721. X    mp = *mpp = ALLOC(am_node);
  722. X    bzero((char *) mp, sizeof(*mp));
  723. X
  724. X    mp->am_mapno = first_free_map++;
  725. X
  726. X    /*
  727. X     * Update free pointer
  728. X     */
  729. X    while (first_free_map < NEXP_AP && exported_ap[first_free_map])
  730. X        first_free_map++;
  731. X
  732. X    if (first_free_map > last_used_map)
  733. X        last_used_map = first_free_map - 1;
  734. X
  735. X#ifdef DEBUG
  736. X    /*dlog("alloc_exp: last_used_map = %d, first_free_map = %d\n",
  737. X        last_used_map, first_free_map);*/
  738. X#endif
  739. X
  740. X    return mp;
  741. X}
  742. X
  743. X/*
  744. X * Free a mount slot
  745. X */
  746. Xvoid exported_ap_free(mp)
  747. Xstruct am_node *mp;
  748. X{
  749. X    /*
  750. X     * Sanity check
  751. X     */
  752. X    if (!mp)
  753. X        return;
  754. X
  755. X    /*
  756. X     * Zero the slot pointer to avoid double free's
  757. X     */
  758. X    exported_ap[mp->am_mapno] = 0;
  759. X
  760. X    /*
  761. X     * Update the free and last_used indices
  762. X     */
  763. X    if (mp->am_mapno == last_used_map)
  764. X        while (last_used_map >= 0 && exported_ap[last_used_map] == 0)
  765. X            --last_used_map;
  766. X
  767. X    if (first_free_map > mp->am_mapno)
  768. X        first_free_map = mp->am_mapno;
  769. X
  770. X#ifdef DEBUG
  771. X    /*dlog("free_exp: last_used_map = %d, first_free_map = %d\n",
  772. X        last_used_map, first_free_map);*/
  773. X#endif
  774. X
  775. X    /*
  776. X     * Free the mount node
  777. X     */
  778. X    free(mp);
  779. X}
  780. X
  781. X/*
  782. X * Insert mp into the correct place,
  783. X * where p_mp is its parent node.
  784. X * A new node gets placed as the youngest sibling
  785. X * of any other children, and the parent's child
  786. X * pointer is adjusted to point to the new child node.
  787. X */
  788. Xvoid insert_am(mp, p_mp)
  789. Xam_node *mp;
  790. Xam_node *p_mp;
  791. X{
  792. X    /*
  793. X     * If this is going in at the root then flag it
  794. X     * so that it cannot be unmounted by amq.
  795. X     */
  796. X    if (p_mp == root_node)
  797. X        mp->am_flags |= AMF_ROOT;
  798. X    /*
  799. X     * Fill in n-way links
  800. X     */
  801. X    mp->am_parent = p_mp;
  802. X    mp->am_osib = p_mp->am_child;
  803. X    if (mp->am_osib)
  804. X        mp->am_osib->am_ysib = mp;
  805. X    p_mp->am_child = mp;
  806. X}
  807. X
  808. X/*
  809. X * Remove am from its place in the mount tree
  810. X */
  811. Xvoid remove_am(mp)
  812. Xam_node *mp;
  813. X{
  814. X    /*
  815. X     * 1.  Consistency check
  816. X     */
  817. X    if (mp->am_child && mp->am_parent) {
  818. X        plog(XLOG_WARNING, "children of \"%s\" still exist - deleting anyway", mp->am_path);
  819. X    }
  820. X
  821. X    /*
  822. X     * 2.  Update parent's child pointer
  823. X     */
  824. X    if (mp->am_parent && mp->am_parent->am_child == mp)
  825. X        mp->am_parent->am_child = mp->am_osib;
  826. X
  827. X    /*
  828. X     * 3.  Unlink from sibling chain
  829. X     */
  830. X    if (mp->am_ysib)
  831. X        mp->am_ysib->am_osib = mp->am_osib;
  832. X    if (mp->am_osib)
  833. X        mp->am_osib->am_ysib = mp->am_ysib;
  834. X}
  835. X
  836. X/*
  837. X * Compute a new time to live value for a node.
  838. X */
  839. Xvoid new_ttl(mp)
  840. Xam_node *mp;
  841. X{
  842. X    mp->am_timeo_w = 0;
  843. X
  844. X    mp->am_ttl = clocktime();
  845. X    mp->am_mnt->mf_fattr.atime.seconds = mp->am_ttl;
  846. X    mp->am_ttl += mp->am_timeo;    /* sun's -tl option */
  847. X}
  848. X
  849. X/*
  850. X * Initialise an allocated mount node.
  851. X * It is assumed that the mount node was bzero'd
  852. X * before getting here so anything that would
  853. X * be set to zero isn't done here.
  854. X */
  855. Xvoid init_map(mp, dir)
  856. Xam_node *mp;
  857. Xchar *dir;
  858. X{
  859. X    /* mp->am_mapno initalised by exported_ap_alloc */
  860. X    mp->am_mnt = new_mntfs();
  861. X    mp->am_name = strdup(dir);
  862. X    mp->am_path = strdup(dir);
  863. X    /*mp->am_link = 0;*/
  864. X    /*mp->am_parent = 0;*/
  865. X    /*mp->am_ysib = 0;*/
  866. X    /*mp->am_osib = 0;*/
  867. X    /*mp->am_child = 0;*/
  868. X    /*mp->am_flags = 0;*/
  869. X    /*mp->am_error = 0;*/
  870. X    mp->am_gen = new_gen();
  871. X    /*mp->am_pref = 0;*/
  872. X
  873. X    mp->am_timeo = am_timeo;
  874. X    new_ttl(mp);
  875. X    mp->am_stats.s_mtime = mp->am_mnt->mf_fattr.atime.seconds;
  876. X    /*mp->am_private = 0;*/
  877. X}
  878. X
  879. X/*
  880. X * Free a mount node.
  881. X * The node must be already unmounted.
  882. X */
  883. Xvoid free_map(mp)
  884. Xam_node *mp;
  885. X{
  886. X    remove_am(mp);
  887. X
  888. X    if (mp->am_link)
  889. X        free(mp->am_link);
  890. X    if (mp->am_name)
  891. X        free(mp->am_name);
  892. X    if (mp->am_path)
  893. X        free(mp->am_path);
  894. X    if (mp->am_pref)
  895. X        free(mp->am_pref);
  896. X
  897. X    if (mp->am_mnt)
  898. X        free_mntfs(mp->am_mnt);
  899. X
  900. X    if (mp->am_flags & AMF_MKPATH)
  901. X        rmdirs(mp->am_path);
  902. X    exported_ap_free(mp);
  903. X}
  904. X
  905. X/*
  906. X * Convert from file handle to
  907. X * automount node.
  908. X */
  909. Xam_node *fh_to_mp3(fhp, rp, c_or_d)
  910. Xnfs_fh *fhp;
  911. Xint *rp;
  912. Xint c_or_d;
  913. X{
  914. X    struct am_fh *fp = (struct am_fh *) fhp;
  915. X    am_node *ap = 0;
  916. X
  917. X    /*
  918. X     * Check process id matches
  919. X     * If it doesn't then it is probably
  920. X     * from an old kernel cached filehandle
  921. X     * which is now out of date.
  922. X     */
  923. X    if (fp->fhh_pid != mypid)
  924. X        goto drop;
  925. X
  926. X    /*
  927. X     * Make sure the index is valid before
  928. X     * exported_ap is referenced.
  929. X     */
  930. X    if (fp->fhh_id < 0 || fp->fhh_id >= NEXP_AP)
  931. X        goto drop;
  932. X
  933. X    /*
  934. X     * Get hold of the supposed mount node
  935. X     */
  936. X    ap = exported_ap[fp->fhh_id];
  937. X
  938. X    /*
  939. X     * If it exists then maybe...
  940. X     */
  941. X    if (ap) {
  942. X        /*
  943. X         * Check the generation number in the node
  944. X         * matches the one from the kernel.  If not
  945. X         * then the old node has been timed out and
  946. X         * a new one allocated.
  947. X         */
  948. X        if (ap->am_gen != fp->fhh_gen) {
  949. X            ap = 0;
  950. X            goto drop;
  951. X        }
  952. X
  953. X        /*
  954. X         * If the node is hung then locate a new node
  955. X         * for it.  This implements the replicated filesystem
  956. X         * retries.
  957. X         */
  958. X        if (ap->am_mnt && FSRV_ISDOWN(ap->am_mnt->mf_server) && ap->am_parent) {
  959. X            int error;
  960. X#ifdef DEBUG
  961. X            dlog("fh_to_mp3: %s (%s) is hung:- call lookup", ap->am_path, ap->am_mnt->mf_info);
  962. X#endif
  963. X            /*
  964. X             * Update last access to original node.  This
  965. X             * avoids timing it out and so sending ESTALE
  966. X             * back to the kernel.
  967. X             */
  968. X            new_ttl(ap);
  969. X
  970. X            /*
  971. X             * Call the parent's lookup routine for an object
  972. X             * with the same name.  This may return -1 in error
  973. X             * if a mount is in progress.  In any case, if no
  974. X             * mount node is returned the error code is propagated
  975. X             * to the caller.
  976. X             */
  977. X            if (c_or_d == VLOOK_CREATE) {
  978. X                ap = (*ap->am_parent->am_mnt->mf_ops->lookuppn)(ap->am_parent,
  979. X                        ap->am_name, &error, c_or_d);
  980. X            } else {
  981. X                ap = 0;
  982. X                error = ESTALE;
  983. X            }
  984. X            if (ap == 0) {
  985. X                *rp = error;
  986. X                return 0;
  987. X            }
  988. X        }
  989. X        /*
  990. X         * Disallow references to objects being unmounted, unless
  991. X         * they are automount points.
  992. X         */
  993. X        if (ap->am_mnt && (ap->am_mnt->mf_flags & MFF_UNMOUNTING) &&
  994. X                !(ap->am_flags & AMF_ROOT)) {
  995. X            *rp = -1;
  996. X            return 0;
  997. X        }
  998. X        new_ttl(ap);
  999. X    }
  1000. X
  1001. Xdrop:
  1002. X    if (!ap || !ap->am_mnt) {
  1003. X        /*
  1004. X         * If we are shutting down then it is likely
  1005. X         * that this node has disappeared because of
  1006. X         * a fast timeout.  To avoid things thrashing
  1007. X         * just pretend it doesn't exist at all.  If
  1008. X         * ESTALE is returned, some NFS clients just
  1009. X         * keep retrying (stupid or what - if it's
  1010. X         * stale now, what's it going to be in 5 minutes?)
  1011. X         */
  1012. X        if (amd_state == Finishing)
  1013. X            *rp = ENOENT;
  1014. X        else
  1015. X            *rp = ESTALE;
  1016. X        amd_stats.d_stale++;
  1017. X    }
  1018. X
  1019. X    return ap;
  1020. X}
  1021. X
  1022. Xam_node *fh_to_mp(fhp)
  1023. Xnfs_fh *fhp;
  1024. X{
  1025. X    int dummy;
  1026. X    return fh_to_mp2(fhp, &dummy);
  1027. X}
  1028. X
  1029. X/*
  1030. X * Convert from automount node to
  1031. X * file handle.
  1032. X */
  1033. Xvoid mp_to_fh(mp, fhp)
  1034. Xam_node *mp;
  1035. Xstruct nfs_fh *fhp;
  1036. X{
  1037. X    struct am_fh *fp = (struct am_fh *) fhp;
  1038. X
  1039. X    /*
  1040. X     * Take the process id
  1041. X     */
  1042. X    fp->fhh_pid = mypid;
  1043. X    /*
  1044. X     * .. the map number
  1045. X     */
  1046. X    fp->fhh_id = mp->am_mapno;
  1047. X    /*
  1048. X     * .. and the generation number
  1049. X     */
  1050. X    fp->fhh_gen = mp->am_gen;
  1051. X    /*
  1052. X     * .. to make a "unique" triple that will never
  1053. X     * be reallocated except across reboots (which doesn't matter)
  1054. X     * or if we are unlucky enough to be given the same
  1055. X     * pid as a previous amd (very unlikely).
  1056. X     */
  1057. X}
  1058. X
  1059. Xstatic am_node *find_ap2(dir, mp)
  1060. Xchar *dir;
  1061. Xam_node *mp;
  1062. X{
  1063. X    if (mp) {
  1064. X        am_node *mp2;
  1065. X        if (strcmp(mp->am_path, dir) == 0)
  1066. X            return mp;
  1067. X
  1068. X        if ((mp->am_mnt->mf_flags & MFF_MOUNTED) &&
  1069. X            strcmp(mp->am_mnt->mf_mount, dir) == 0)
  1070. X            return mp;
  1071. X
  1072. X        mp2 = find_ap2(dir, mp->am_osib);
  1073. X        if (mp2)
  1074. X            return mp2;
  1075. X        return find_ap2(dir, mp->am_child);
  1076. X    }
  1077. X
  1078. X    return 0;
  1079. X}
  1080. X
  1081. X/*
  1082. X * Find the mount node corresponding
  1083. X * to dir.  dir can match either the
  1084. X * automount path or, if the node is
  1085. X * mounted, the mount location.
  1086. X */
  1087. Xam_node *find_ap(dir)
  1088. Xchar *dir;
  1089. X{
  1090. X    int i;
  1091. X
  1092. X    for (i = last_used_map; i >= 0; --i) {
  1093. X        am_node *mp = exported_ap[i];
  1094. X        if (mp && (mp->am_flags & AMF_ROOT)) {
  1095. X            mp = find_ap2(dir, exported_ap[i]);
  1096. X            if (mp)
  1097. X                return mp;
  1098. X        }
  1099. X    }
  1100. X
  1101. X    return 0;
  1102. X}
  1103. X
  1104. X/*
  1105. X * Get the filehandle for a particular named directory.
  1106. X * This is used during the bootstrap to tell the kernel
  1107. X * the filehandles of the initial automount points.
  1108. X */
  1109. Xnfs_fh *root_fh(dir)
  1110. Xchar *dir;
  1111. X{
  1112. X    static nfs_fh nfh;
  1113. X    am_node *mp = root_ap(dir, TRUE);
  1114. X    if (mp) {
  1115. X        mp_to_fh(mp, &nfh);
  1116. X        return &nfh;
  1117. X    }
  1118. X
  1119. X    /*
  1120. X     * Should never get here...
  1121. X     */
  1122. X    plog(XLOG_ERROR, "Can't find root filehandle for %s", dir);
  1123. X    return 0;
  1124. X}
  1125. X
  1126. Xam_node *root_ap(dir, path)
  1127. Xchar *dir;
  1128. Xint path;
  1129. X{
  1130. X    am_node *mp = find_ap(dir);
  1131. X    if (mp && mp->am_parent == root_node)
  1132. X        return mp;
  1133. X
  1134. X    return 0;
  1135. X}
  1136. X
  1137. X/*
  1138. X * Mount a top level automount node
  1139. X * by calling lookup in the parent
  1140. X * (root) node which will cause the
  1141. X * automount node to be automounted (!)
  1142. X */
  1143. Xstatic void mount_auto_node(dir)
  1144. Xchar *dir;
  1145. X{
  1146. X    int error = 0;
  1147. X    (void) afs_ops.lookuppn(root_node, dir, &error, VLOOK_CREATE);
  1148. X    if (error) {
  1149. X        errno = error; /* XXX */
  1150. X        plog(XLOG_ERROR, "Could not start server on %s: %m", dir);
  1151. X    }
  1152. X}
  1153. X
  1154. X/*
  1155. X * Cause all the top-level mount nodes
  1156. X * to be automounted
  1157. X */
  1158. Xint mount_exported()
  1159. X{
  1160. X    /*
  1161. X     * Iterate over all the nodes to be started
  1162. X     */
  1163. X    return root_keyiter(mount_auto_node);
  1164. X}
  1165. X
  1166. X/*
  1167. X * Construct top-level node
  1168. X */
  1169. Xvoid make_root_node()
  1170. X{
  1171. X    mntfs *root_mnt;
  1172. X    char *rootmap = ROOT_MAP;
  1173. X    root_node = exported_ap_alloc();
  1174. X
  1175. X    init_map(root_node, "");
  1176. X    root_mnt = find_mntfs(&afs_ops, (am_opts *) 0, "", rootmap, "");
  1177. X    root_mnt->mf_mount = strealloc(root_mnt->mf_mount, pid_fsname);
  1178. X    root_mnt->mf_private = (voidp) mapc_find(rootmap, "");
  1179. X    root_mnt->mf_prfree = mapc_free;
  1180. X    free_mntfs(root_node->am_mnt);
  1181. X    root_node->am_mnt = root_mnt;
  1182. X    root_node->am_flags |= AMF_NOTIMEOUT;
  1183. X    root_mnt->mf_error = 0;
  1184. X}
  1185. X
  1186. X/*
  1187. X * Cause all the nodes to be unmounted by timing
  1188. X * them out.
  1189. X */
  1190. Xvoid umount_exported(P_void)
  1191. X{
  1192. X    int i;
  1193. X    for (i = last_used_map; i >= 0; --i) {
  1194. X        am_node *mp = exported_ap[i];
  1195. X        if (mp) {
  1196. X            mntfs *mf = mp->am_mnt;
  1197. X            if (mf->mf_flags & MFF_UNMOUNTING) {
  1198. X                /*
  1199. X                 * If this node is being unmounted then
  1200. X                 * just ignore it.  However, this could
  1201. X                 * prevent amd from finishing if the
  1202. X                 * unmount gets blocked since the am_node
  1203. X                 * will never be free'd.  am_unmounted needs
  1204. X                 * telling about this possibility. - XXX
  1205. X                 */
  1206. X                continue;
  1207. X            }
  1208. X            if (mf && mf->mf_ops == &dfs_ops) {
  1209. X                /*
  1210. X                 * When shutting down this had better
  1211. X                 * look like a directory, otherwise it
  1212. X                 * can't be unmounted!
  1213. X                 */
  1214. X                mf->mf_fattr.type = NFDIR;
  1215. X                mf->mf_fattr.mode = NFSMODE_DIR | 0555;
  1216. X            }
  1217. X            if ((--immediate_abort < 0 && !(mp->am_flags & AMF_ROOT) && mp->am_parent) ||
  1218. X                (mf->mf_flags & MFF_RESTART)) {
  1219. X                /*
  1220. X                 * Just throw this node away without
  1221. X                 * bothering to unmount it.  If the
  1222. X                 * server is not known to be up then
  1223. X                 * don't discard the mounted on directory
  1224. X                 * or Amd might hang...
  1225. X                 */
  1226. X                if (mf->mf_server &&
  1227. X                    (mf->mf_server->fs_flags & (FSF_DOWN|FSF_VALID)) != FSF_VALID)
  1228. X                    mf->mf_flags &= ~MFF_MKMNT;
  1229. X                am_unmounted(mp);
  1230. X            } else {
  1231. X                /*
  1232. X                 * Any other node gets forcibly
  1233. X                 * timed out
  1234. X                 */
  1235. X                mp->am_flags &= ~AMF_NOTIMEOUT;
  1236. X                mp->am_mnt->mf_flags &= ~MFF_RSTKEEP;
  1237. X                mp->am_ttl = 0;
  1238. X                mp->am_timeo = 1;
  1239. X                mp->am_timeo_w = 0;
  1240. X            }
  1241. X        }
  1242. X    }
  1243. X}
  1244. X
  1245. Xstatic int unmount_node P((am_node *mp));
  1246. Xstatic int unmount_node(mp)
  1247. Xam_node *mp;
  1248. X{
  1249. X    mntfs *mf = mp->am_mnt;
  1250. X    int error;
  1251. X
  1252. X    if ((mf->mf_flags & MFF_ERROR) || mf->mf_refc > 1) {
  1253. X        /*
  1254. X         * Just unlink
  1255. X         */
  1256. X#ifdef DEBUG
  1257. X        if (mf->mf_flags & MFF_ERROR)
  1258. X            dlog("No-op unmount of error node %s", mf->mf_info);
  1259. X#endif
  1260. X        error = 0;
  1261. X    } else {
  1262. X#ifdef DEBUG
  1263. X        dlog("Unmounting %s (%s)", mf->mf_mount, mf->mf_info);
  1264. X#endif
  1265. X        error = (*mf->mf_ops->umount_fs)(mp);
  1266. X    }
  1267. X
  1268. X    if (error) {
  1269. X#ifdef DEBUG
  1270. X        errno = error; /* XXX */
  1271. X        dlog("%s: unmount: %m", mf->mf_mount);
  1272. X#endif
  1273. X    }
  1274. X
  1275. X    return error;
  1276. X}
  1277. X
  1278. Xstatic int unmount_node_wrap P((voidp vp));
  1279. Xstatic int unmount_node_wrap(vp)
  1280. Xvoidp vp;
  1281. X{
  1282. X    /*
  1283. X     * This code should just say:
  1284. X     * return unmount_node((am_node *) vp);
  1285. X     *
  1286. X     * However...
  1287. X     * The kernel keeps a cached copy of filehandles,
  1288. X     * and doesn't ever cache them (apparently).  So
  1289. X     * when Amd times out a node the kernel will have a
  1290. X     * stale filehandle.  When the kernel next uses the
  1291. X     * filehandle it gets ESTALE.
  1292. X     *
  1293. X     * The workaround:
  1294. X     * Arrange that when a node is removed an unlink or
  1295. X     * rmdir is done on that path so that the kernel
  1296. X     * cache is done.  Yes - yuck.
  1297. X     *
  1298. X     * This can all be removed (and the background
  1299. X     * unmount flag in sfs_ops) if/when the kernel does
  1300. X     * something smarter.
  1301. X     */
  1302. X    am_node *mp = (am_node *) vp;
  1303. X    int isauto = mp->am_parent && (mp->am_parent->am_mnt->mf_fattr.type == NFDIR);
  1304. X    int error = unmount_node(mp);
  1305. X    if (error)
  1306. X        return error;
  1307. X    if (isauto && (int)amd_state < (int)Finishing) {
  1308. X        int islink = (mp->am_mnt->mf_fattr.type == NFLNK);
  1309. X        int isdir = (mp->am_mnt->mf_fattr.type == NFDIR);
  1310. X        if (islink) {
  1311. X            if (unlink(mp->am_path) < 0)
  1312. X                return errno;
  1313. X        } else if (isdir) {
  1314. X            if (rmdir(mp->am_path) < 0)
  1315. X                return errno;
  1316. X        }
  1317. X    }
  1318. X    return 0;
  1319. X}
  1320. X
  1321. Xstatic void free_map_if_success(rc, term, closure)
  1322. Xint rc;
  1323. Xint term;
  1324. Xvoidp closure;
  1325. X{
  1326. X    am_node *mp = (am_node *) closure;
  1327. X    mntfs *mf = mp->am_mnt;
  1328. X
  1329. X    /*
  1330. X     * Not unmounting any more
  1331. X     */
  1332. X    mf->mf_flags &= ~MFF_UNMOUNTING;
  1333. X
  1334. X    /*
  1335. X     * If a timeout was defered because the underlying filesystem
  1336. X     * was busy then arrange for a timeout as soon as possible.
  1337. X     */
  1338. X    if (mf->mf_flags & MFF_WANTTIMO) {
  1339. X        mf->mf_flags &= ~MFF_WANTTIMO;
  1340. X        reschedule_timeout_mp();
  1341. X    }
  1342. X
  1343. X    if (term) {
  1344. X        plog(XLOG_ERROR, "unmount for %s got signal %d", mp->am_path, term);
  1345. X#ifdef DEBUG
  1346. X        /*
  1347. X         * dbx likes to put a trap on exit().
  1348. X         * Pretend it succeeded for now...
  1349. X         */
  1350. X        if (term == SIGTRAP) {
  1351. X            am_unmounted(mp);
  1352. X        }
  1353. X#endif
  1354. X        amd_stats.d_uerr++;
  1355. X    } else if (rc) {
  1356. X        if (rc == EBUSY) {
  1357. X            plog(XLOG_STATS, "\"%s\" on %s still active", mp->am_path, mf->mf_mount);
  1358. X        } else {
  1359. X            errno = rc;    /* XXX */
  1360. X            plog(XLOG_ERROR, "%s: unmount: %m", mp->am_path);
  1361. X        }
  1362. X        amd_stats.d_uerr++;
  1363. X    } else {
  1364. X        am_unmounted(mp);
  1365. X    }
  1366. X
  1367. X    /*
  1368. X     * Wakeup anything waiting for this mount
  1369. X     */
  1370. X    wakeup((voidp) mf);
  1371. X}
  1372. X
  1373. Xstatic void unmount_mp(mp)
  1374. Xam_node *mp;
  1375. X{
  1376. X    mntfs *mf = mp->am_mnt;
  1377. X#ifdef notdef
  1378. X    plog(XLOG_INFO, "\"%s\" on %s timed out", mp->am_path, mp->am_mnt->mf_mount);
  1379. X#endif
  1380. X    if ((mf->mf_ops->fs_flags & FS_UBACKGROUND) &&
  1381. X            (mf->mf_flags & MFF_MOUNTED) /* &&
  1382. X            mf->mf_refc == 1 */) {
  1383. X        if (FSRV_ISDOWN(mf->mf_server)) {
  1384. X            /*
  1385. X             * Don't try to unmount from a server that is known to be down
  1386. X             */
  1387. X            if (!(mf->mf_flags & MFF_LOGDOWN)) {
  1388. X                /* Only log this once, otherwise gets a bit boring */
  1389. X                plog(XLOG_STATS, "file server %s is down - timeout of \"%s\" ignored", mf->mf_server->fs_host, mp->am_path);
  1390. X                mf->mf_flags |= MFF_LOGDOWN;
  1391. X            }
  1392. X        } else {
  1393. X            /* Clear logdown flag - since the server must be up */
  1394. X            mf->mf_flags &= ~MFF_LOGDOWN;
  1395. X#ifdef DEBUG
  1396. X            /*dlog("Will background the unmount attempt");*/
  1397. X#endif
  1398. X            /*
  1399. X             * Note that we are unmounting this node
  1400. X             */
  1401. X            mf->mf_flags |= MFF_UNMOUNTING;
  1402. X            run_task(unmount_node_wrap, (voidp) mp,
  1403. X                 free_map_if_success, (voidp) mp);
  1404. X#ifdef DEBUG
  1405. X            dlog("unmount attempt backgrounded");
  1406. X#endif
  1407. X        }
  1408. X    } else {
  1409. X#ifdef DEBUG
  1410. X        dlog("Trying unmount in foreground");
  1411. X#endif
  1412. X        mf->mf_flags |= MFF_UNMOUNTING;
  1413. X        free_map_if_success(unmount_node(mp), 0, (voidp) mp);
  1414. X#ifdef DEBUG
  1415. X        dlog("unmount attempt done");
  1416. X#endif
  1417. X    }
  1418. X}
  1419. X
  1420. Xvoid timeout_mp()
  1421. X{
  1422. X#define NEVER (time_t) 0
  1423. X#define    smallest_t(t1, t2) \
  1424. X    (t1 != NEVER ? (t2 != NEVER ? (t1 < t2 ? t1 : t2) : t1) : t2)
  1425. X#define IGNORE_FLAGS (MFF_MOUNTING|MFF_UNMOUNTING|MFF_RESTART)
  1426. X
  1427. X    int i;
  1428. X    time_t t = NEVER;
  1429. X    time_t now = clocktime();
  1430. X
  1431. X#ifdef DEBUG
  1432. X    dlog("Timing out automount points...");
  1433. X#endif
  1434. X    for (i = last_used_map; i >= 0; --i) {
  1435. X        am_node *mp = exported_ap[i];
  1436. X        mntfs *mf;
  1437. X        /*
  1438. X         * Just continue if nothing mounted, or can't be timed out.
  1439. X         */
  1440. X        if (!mp || (mp->am_flags & AMF_NOTIMEOUT))
  1441. X            continue;
  1442. X        /*
  1443. X         * Pick up mounted filesystem
  1444. X         */
  1445. X        mf = mp->am_mnt;
  1446. X        if (!mf)
  1447. X            continue;
  1448. X        /*
  1449. X         * Don't delete last reference to a restarted filesystem.
  1450. X         */
  1451. X        if ((mf->mf_flags & MFF_RSTKEEP) && mf->mf_refc == 1)
  1452. X            continue;
  1453. X        /*
  1454. X         * If there is action on this filesystem then ignore it
  1455. X         */
  1456. X        if (!(mf->mf_flags & IGNORE_FLAGS)) {
  1457. X            int expired = 0;
  1458. X            mf->mf_flags &= ~MFF_WANTTIMO;
  1459. X#ifdef DEBUG
  1460. X            /*dlog("t is initially @%d, zero in %d secs", t, t - now);*/
  1461. X#endif
  1462. X            if (now >= mp->am_ttl) {
  1463. X                expired = 1;
  1464. X                /*
  1465. X                 * Move the ttl forward to avoid thrashing effects
  1466. X                 * on the next call to timeout!
  1467. X                 */
  1468. X                /* sun's -tw option */
  1469. X                if (mp->am_timeo_w < 4 * am_timeo_w)
  1470. X                    mp->am_timeo_w += am_timeo_w;
  1471. X                mp->am_ttl = now + mp->am_timeo_w;
  1472. X            }
  1473. X            /*
  1474. X             * If the next ttl is smallest, use that
  1475. X             */
  1476. X            t = smallest_t(t, mp->am_ttl);
  1477. X
  1478. X#ifdef DEBUG
  1479. X            /*dlog("after ttl t is @%d, zero in %d secs", t, t - now);*/
  1480. X#endif
  1481. X
  1482. X            if (!mp->am_child && mf->mf_error >= 0 && expired)
  1483. X                unmount_mp(mp);
  1484. X        } else if (mf->mf_flags & MFF_UNMOUNTING) {
  1485. X            mf->mf_flags |= MFF_WANTTIMO;
  1486. X        }
  1487. X    }
  1488. X
  1489. X    if (t == NEVER) {
  1490. X#ifdef DEBUG
  1491. X        dlog("No further timeouts");
  1492. X#endif
  1493. X        t = now + ONE_HOUR;
  1494. X    }
  1495. X
  1496. X    /*
  1497. X     * Sanity check to avoid runaways.
  1498. X     * Absolutely should never get this but
  1499. X     * if you do without this trap amd will thrash.
  1500. X     */
  1501. X    if (t <= now) {
  1502. X        t = now + 6;    /* XXX */
  1503. X        plog(XLOG_ERROR, "Got a zero interval in timeout_mp()!");
  1504. X    }
  1505. X    /*
  1506. X     * XXX - when shutting down, make things happen faster
  1507. X     */
  1508. X    if ((int)amd_state >= (int)Finishing)
  1509. X        t = now + 1;
  1510. X#ifdef DEBUG
  1511. X    dlog("Next mount timeout in %ds", t - now);
  1512. X#endif
  1513. X
  1514. X    timeout_mp_id = timeout(t - now, timeout_mp, 0);
  1515. X
  1516. X#undef NEVER
  1517. X#undef smallest_t
  1518. X#undef IGNORE_FLAGS
  1519. X}
  1520. X
  1521. X/*
  1522. X * Cause timeout_mp to be called soonest
  1523. X */
  1524. Xvoid reschedule_timeout_mp()
  1525. X{
  1526. X    if (timeout_mp_id)
  1527. X        untimeout(timeout_mp_id);
  1528. X    timeout_mp_id = timeout(0, timeout_mp, 0);
  1529. X}
  1530. END_OF_FILE
  1531. if test 19814 -ne `wc -c <'map.c'`; then
  1532.     echo shar: \"'map.c'\" unpacked with wrong size!
  1533. fi
  1534. # end of 'map.c'
  1535. fi
  1536. echo shar: End of archive 10 \(of 13\).
  1537. cp /dev/null ark10isdone
  1538. MISSING=""
  1539. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 ; do
  1540.     if test ! -f ark${I}isdone ; then
  1541.     MISSING="${MISSING} ${I}"
  1542.     fi
  1543. done
  1544. if test "${MISSING}" = "" ; then
  1545.     echo You have unpacked all 13 archives.
  1546.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1547. else
  1548.     echo You still need to unpack the following archives:
  1549.     echo "        " ${MISSING}
  1550. fi
  1551. ##  End of shell archive.
  1552. exit 0
  1553. exit 0 # Just in case...
  1554.